package com.ushine.web.template.validation.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ushine.web.component.authority.DataFilterTypeEnum;
import com.ushine.web.component.contant.UniquenessEnum;
import com.ushine.web.component.exception.ServiceException;
import com.ushine.web.component.exception.ServiceExceptionEnum;
import com.ushine.web.component.page.PageRequestQuery;
import com.ushine.web.template.validation.mapper.ValidationMapper;
import com.ushine.web.template.validation.model.ValidationAndRoleDO;
import com.ushine.web.template.validation.model.ValidationDO;
import com.ushine.web.template.validation.service.IValidationAndRoleService;
import com.ushine.web.template.validation.service.IValidationService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author: yls
 * @Date 2022/3/17 17:11
 * @Description: 数据校验实现类
 * @Version 1.0
 **/
@Validated
@Service
public class ValidationServiceImpl extends ServiceImpl<ValidationMapper, ValidationDO> implements IValidationService {

    @Resource
    private IValidationAndRoleService validationAndRoleService;

    @Override
    @Transactional(readOnly = true)
    public void validatedUniqueness(@NotNull(message = "数据实体不能为null") @Valid ValidationDO validation,
                                    @NotNull(message = "操作类型不能为空") UniquenessEnum uniquenessEnum) throws ServiceException {
        /*
         * 数据唯一性校验：username 用户名唯一
         */
        LambdaQueryWrapper<ValidationDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ValidationDO::getUsername, validation.getUsername());
        /*
         * 修改数据在唯一性验证上要过滤掉当前数据
         */
        if (UniquenessEnum.UPDATE.equals(uniquenessEnum)) {
            lambdaQueryWrapper.ne(ValidationDO::getId, validation.getId());
        }
        /*
         * 统计唯一性键的数据
         */
        int count = count(lambdaQueryWrapper);
        if (count > 0) {
            throw new ServiceException(ServiceExceptionEnum.EXIST_SAME_NAME_DATA);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertValidation(@NotNull(message = "数据实体不能为null") @Valid ValidationDO validation) throws ServiceException {
        // 根据用户名验证数据唯一性
        validatedUniqueness(validation, UniquenessEnum.INSERT);
        // 数据唯一性校验通过，开始提交数据
        return save(validation);
    }


    @Override
    @Transactional(rollbackFor = Exception.class,isolation = Isolation.SERIALIZABLE)
    public Boolean updateValidation(@NotNull(message = "数据实体不能为null") @Valid ValidationDO validation) throws ServiceException {
        // 验证数据喂唯一性
        validatedUniqueness(validation, UniquenessEnum.UPDATE);
        // 数据唯一性校验通过，开始提交数据
        return updateById(validation);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteValidation(@NotEmpty(message = "id集合不能为空") Collection<Long> ids) throws ServiceException {
        /*
         * 如有关联数据，查询关联数据
         */
        Integer integer = validationAndRoleService.countValidationAndRole(ids);
        if (integer > 0) {
            // 存在同名数据无法删除
            throw new ServiceException(ServiceExceptionEnum.EXIST_LINKED_DATA);
        }
        // 关联数据验证通过，可以进行删除
        return removeByIds(ids);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean deleteValidationAndLinkData(@NotEmpty(message = "id集合不能为空") Collection<Long> ids) throws ServiceException {
        boolean flag = removeByIds(ids);
        /*
         * 如有关联数据，查询关联数据
         */
        List<ValidationAndRoleDO> validationAndRoles = validationAndRoleService.listValidationAndRoles(ids);
        // 集合判空多用工具类
        if (!CollectionUtils.isEmpty(validationAndRoles)) {
            Set<Long> collect = validationAndRoles.stream().map(ValidationAndRoleDO::getId).collect(Collectors.toSet());
            // 存在关联数据，先删除关联数据
            Boolean tempFlag = validationAndRoleService.batchDeleteValidationAndRole(collect);
        }

        /*
         * 模拟事务异常
         */
        if (Boolean.TRUE.equals(flag)) {
            throw new ServiceException(ServiceExceptionEnum.EXIST_LINKED_DATA);
        }
        // 关联数据验证通过，返回结果
        return flag;
    }

    @Override
    @Transactional(readOnly = true,isolation = Isolation.SERIALIZABLE)
    public Optional<ValidationDO> getValidation(@NotNull(message = "id不能为null") Long id) throws ServiceException {
        // 查询单个数据统一用Optional返回，便于空指针处理
        ValidationDO validation = getById(id);
        if (validation == null) {
            throw new ServiceException(ServiceExceptionEnum.NOT_EXIST_DATA);
        }
        return Optional.of(validation);
    }

    @Override
    @Transactional(readOnly = true)
    public Page<ValidationDO> listValidationsByPage(@NotNull(message = "分页对象不能为空") PageRequestQuery<ValidationDO> pageRequestQuery) {
        Page<ValidationDO> page = new Page<>(pageRequestQuery.getPageNum(), pageRequestQuery.getPageSize());
        LambdaQueryWrapper<ValidationDO> queryWrapper = new LambdaQueryWrapper<>();
        return page(page, queryWrapper);
    }

    @Override
    public String branchDemo(UniquenessEnum firstBranchVar, DataFilterTypeEnum secondBranchVar) {
        if (UniquenessEnum.UPDATE.equals(firstBranchVar)){
            // 如果分支类型是从数据库查询出来的，就在数据库模拟所有类型的数据
            if (DataFilterTypeEnum.SELF.equals(secondBranchVar)){
                return "分支：1";
            }
            if (DataFilterTypeEnum.SELF_CREATE.equals(secondBranchVar)){
                return "分支：2";
            }
            if (DataFilterTypeEnum.DEPT_SETS.equals(secondBranchVar)){
                return "分支：3";
            }
            if (DataFilterTypeEnum.DEPT.equals(secondBranchVar)){
                return "分支：4";
            }
            if (DataFilterTypeEnum.DIY.equals(secondBranchVar)){
                return "分支：5";
            }
        }else if (UniquenessEnum.INSERT.equals(firstBranchVar)){
            if (DataFilterTypeEnum.SELF.equals(secondBranchVar)){
                return "分支：6";
            }
            if (DataFilterTypeEnum.SELF_CREATE.equals(secondBranchVar)){
                return "分支：7";
            }
            if (DataFilterTypeEnum.DEPT_SETS.equals(secondBranchVar)){
                return "分支：8";
            }
            if (DataFilterTypeEnum.DEPT.equals(secondBranchVar)){
                return "分支：9";
            }
            if (DataFilterTypeEnum.DIY.equals(secondBranchVar)){
                return "分支：10";
            }
        }else {
            if (DataFilterTypeEnum.SELF.equals(secondBranchVar)){
                return "分支：11";
            }
            if (DataFilterTypeEnum.SELF_CREATE.equals(secondBranchVar)){
                return "分支：12";
            }
            if (DataFilterTypeEnum.DEPT_SETS.equals(secondBranchVar)){
                return "分支：13";
            }
            if (DataFilterTypeEnum.DEPT.equals(secondBranchVar)){
                return "分支：14";
            }
            if (DataFilterTypeEnum.DIY.equals(secondBranchVar)){
                return "分支：15";
            }
        }
        return "不存在的分支";
    }
}
